import gi
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk, Gio, GLib
import threading
import time

# 读取 D-Bus 接口 XML 文件
with open("com.example.DBusService.xml", "r") as f:
    introspection_data = Gio.DBusNodeInfo.new_for_xml(f.read())

class DBusService(Gio.DBusInterfaceSkeleton):
    __gtype_name__ = 'DBusService'

    def __init__(self):
        # super().__init__(interface_info=introspection_data.interfaces[0])
        super().__init__()
        self.connection = None

    def do_get_info(self):
        return introspection_data.interfaces[0]

    # def do_get_properties(self):
    #     return []

    # def do_flush(self):
    #     pass

    # def do_g_authorize_method(self, invocation, method_info):
    #     return True

    def emit_message(self, message):
        # 发送信号到主线程
        self.emit_signal(None, "/com/example/DBusService", "com.example.DBusService", "OnMessage", GLib.Variant("(s)", (message,)))

    def handle_emit_message(self, connection, sender, object_path, interface_name, method_name, parameters, invocation):
        message = parameters.unpack()[0]
        self.emit_message(message)
        invocation.return_value(None)

class MyWindow(Gtk.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_title("DBus Example")
        self.set_default_size(200, 100)

        # 创建一个标签用于显示消息
        self.label = Gtk.Label(label="Waiting for messages...")
        self.set_child(self.label)

        # 创建 D-Bus 服务
        self.dbus_service = DBusService()
        self.connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
        self.dbus_service.export(self.connection, "/com/example/DBusService")
        self.dbus_service.connect("g-signal", self.on_dbus_signal)

    def on_dbus_signal(self, interface, sender_name, object_path, interface_name, signal_name, parameters):
        if signal_name == "OnMessage":
            message = parameters.unpack()[0]
            GLib.idle_add(self.update_label, message)

    def update_label(self, message):
        self.label.set_label(message)

def worker_function(dbus_service):
    for i in range(5):
        # 模拟子线程发送消息
        dbus_service.emit_message(f"Message {i}")
        time.sleep(1)

if __name__ == "__main__":
    app = Gtk.Application(application_id="com.example.DBusApp")

    def on_activate(app):
        window = MyWindow(application=app)
        window.present()

        # 启动子线程
        threading.Thread(target=worker_function, args=(window.dbus_service,), daemon=True).start()

    app.connect("activate", on_activate)
    app.run()